

package java.lang;

import sun.nio.ch.Interruptible;
import sun.reflect.CallerSensitive;
import sun.reflect.Reflection;
import sun.security.util.SecurityConstants;

import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;


public class Thread implements Runnable {


    private static native void registerNatives();

    static {
        registerNatives();
    }

    private volatile String name;
    private int priority;
    private Thread threadQ;
    private long eetop;
    private boolean single_step;
    private boolean daemon = false;
    private boolean stillborn = false;
    private Runnable target;
    private ThreadGroup group;               // 线程组
    private ClassLoader contextClassLoader;
    private AccessControlContext inheritedAccessControlContext;


    // 线程初始编号,简单的递增计数器.
    // 如果创建线程时没有指定线程名，那线程名就会是:
    //Thread-0, Thread-1, Thread-2, Thread-3,
    private static int threadInitNumber;

    private static synchronized int nextThreadNum() {
        return threadInitNumber++;
    }



    // 定义一个ThreadLocalMap实例，用于当前线程独占的变量
    ThreadLocal.ThreadLocalMap threadLocals = null;
    // 定义一个可继承的ThreadLocalMap实例，用于子线程可以继承父线程的变量
    ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;




    private long stackSize;
    private long nativeParkEventPointer;
    private long tid;
    private static long threadSeqNumber;
    private volatile int threadStatus = 0;

    private static synchronized long nextThreadID() {
        return ++threadSeqNumber;
    }

    volatile Object parkBlocker;
    private volatile Interruptible blocker;
    private final Object blockerLock = new Object();


    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }


    /**
     * 定义最小的优先级级别。
     * 该常量用于标识任务或事件的最低优先级水平。
     * 在多线程或事件处理环境中，优先级较高的任务或事件通常会被优先处理。
     */
    public final static int MIN_PRIORITY = 1;

    /**
     * 定义常量NORM_PRIORITY，用于设定某种操作或事件的优先级。
     * 该优先级被设定为5，表明该操作或事件的处理重要性相对平均。
     * 使用静态常量的好处是，可以在不创建类实例的情况下访问它，
     * 并且保证了该优先级值在程序的整个生命周期内保持不变。
     */
    public final static int NORM_PRIORITY = 5;

    /**
     * 定义线程的最高优先级。
     * 优先级高的线程更有可能被调度执行。
     * Java线程的优先级范围是1到10，其中1为最低优先级，10为最高优先级。
     */
    public final static int MAX_PRIORITY = 10;


    // native 方法

    /**
     * 获取当前正在执行的线程对象
     * 此方法是 native 方法，意味着它由底层操作系统或虚拟机直接实现，而不是用 Java 代码实现
     * 它用于获取当前线程的对象，这对于线程管理、同步控制等操作非常关键
     *
     * @return 当前正在执行的线程对象
     */
    public static native Thread currentThread();


    /**
     * 确保在多线程环境下执行当前线程的后续操作前，当前线程不会继续执行。
     * 此方法建议在需要明确控制线程执行顺序时使用。
     */
    public static native void yield();


    /**
     * 使当前线程暂停执行指定的时间
     * 通过调用此方法，可以使当前正在执行的线程暂停执行指定数量的毫秒
     * 这对于控制程序执行速度或实现某些程序逻辑（如模拟延时）时非常有用
     *
     * @param millis 暂停执行的毫秒数必须为非负值
     * @throws InterruptedException 如果在调用此方法期间，当前线程被中断，将抛出此异常
     */
    public static native void sleep(long millis) throws InterruptedException;


    /**
     * 精确睡眠方法，允许指定睡眠时间到纳秒级别
     * 此方法通过调整毫秒和纳秒的值，确保睡眠时间尽可能接近指定的持续时间
     *
     * @param millis 睡眠时间的毫秒部分
     * @param nanos  睡眠时间的纳秒部分，必须在0到999999之间
     * @throws InterruptedException     如果睡眠期间被中断
     * @throws IllegalArgumentException 如果millis或nanos参数不符合要求
     */
    public static void sleep(long millis, int nanos) throws InterruptedException {
        // 检查毫秒值是否为负，如果是，则抛出异常
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        // 检查纳秒值是否超出范围，如果是，则抛出异常
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }
        // 根据纳秒值决定是否需要调整毫秒值，以确保时间计算的准确性
        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }
        // 调用重载的sleep方法，执行实际的睡眠操作
        sleep(millis);
    }


    /**
     * 重写clone方法以禁止对象的克隆
     * 此方法通过抛出CloneNotSupportedException异常来明确表示该类的实例不能被克隆
     * 这种实现阻止了其他代码尝试对不可克隆的对象进行克隆操作，从而保护了对象的完整性
     *
     * @return 从未返回，因为总是抛出异常
     * @throws CloneNotSupportedException 总是抛出，表明对象不能被克隆
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }


    /*
     * 构造方法
     */
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

    public Thread(String name) {
        init(null, null, name, 0);
    }

    public Thread(Runnable target, String name) {
        init(null, target, name, 0);
    }

    public Thread(Runnable target, AccessControlContext acc) {
        init(null, target, "Thread-" + nextThreadNum(), 0, acc);
    }

    public Thread(ThreadGroup group, Runnable target) {
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }

    public Thread(ThreadGroup group, String name) {
        init(group, null, name, 0);
    }

    public Thread(ThreadGroup group, Runnable target, String name) {
        init(group, target, name, 0);
    }

    public Thread(ThreadGroup group, Runnable target, String name, long stackSize) {
        init(group, target, name, stackSize);
    }


    /**
     * 初始化线程
     *
     * @param g         线程组，用于组织和管理一组线程
     * @param target    实现Runnable接口的对象，代表线程执行的任务
     * @param name      线程的名称，用于标识线程
     * @param stackSize 线程栈的大小，用于设置线程运行时所需的最大内存空间
     */
    private void init(ThreadGroup g, Runnable target, String name, long stackSize) {
        // 调用另一个重载的init方法，传入线程组、任务、名称、栈大小以及null作为附加参数
        init(g, target, name, stackSize, null);
    }


    /**
     * 创建线程的真实方法
     *
     * @param g         线程组
     * @param target    Runnable对象  创建一个线程实例最重要的
     * @param name      线程的名字
     * @param stackSize 为线程分配的栈的大小，若为0则表示忽略这个参数
     * @param acc
     */
    private void init(ThreadGroup g, Runnable target, String name, long stackSize, AccessControlContext acc) {
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
        this.name = name;
        Thread parent = currentThread();
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            if (security != null) {
                g = security.getThreadGroup();
            }
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        g.checkAccess();

        if (security != null) {
            if (isCCLOverridden(getClass())) {
                security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
            }
        }

        g.addUnstarted();

        this.group = g;
        this.daemon = parent.isDaemon();
        this.priority = parent.getPriority();
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext =
                acc != null ? acc : AccessController.getContext();
        this.target = target;
        setPriority(priority);
        if (parent.inheritableThreadLocals != null)
            this.inheritableThreadLocals =
                    ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }


    /**
     * 启动此线程。
     * 此方法用于启动线程，使其开始执行。线程将在自己的上下文中执行其 run 方法。
     *
     * @throws IllegalThreadStateException 如果线程已经启动或已被停止。
     */
    public synchronized void start() {

        // 检查线程是否已经启动
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* 通知线程组此线程即将启动，
         * 以便将其添加到线程组的线程列表中，
         * 并减少线程组的未启动计数。 */
        group.add(this);

        // 标记线程是否已成功启动
        boolean started = false;
        try {
            // 调用低级别启动方法以开始线程执行
            start0();
            started = true;
        } finally {
            // 如果线程启动失败，通知线程组
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
            /* 不做任何处理。如果 start0 抛出异常，
              则该异常将传递给调用堆栈。 */
            }
        }
    }


    private native void start0();


    /**
     * run方法仅仅是调用了target对象的run方法
     * 如果我们在线程构造时没有传入target（例如调用了无参构造函数）
     * 那么这个run方法就什么也不会做。
     */
    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }


    /**
     * 退出当前线程并清理资源
     * 当线程终止时，此方法确保线程所属的组得到通知，并且线程被从组中移除
     * 此外，为了加速垃圾回收，方法会显式地置空所有引用字段
     * 这是必要的，因为长时间运行的线程可能持有大量对象的引用，从而延迟垃圾回收
     */
    private void exit() {
        // 通知线程组当前线程已终止，并解除与线程组的关联
        if (group != null) {
            group.threadTerminated(this);
            group = null;
        }
        // 显式地置空所有引用字段，以加速垃圾回收
        /* Aggressively null out all reference fields: see bug 4006245 */
        target = null;
        // 以下代码进一步加速释放与线程相关的资源
        threadLocals = null;
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }



    /**
     * 停止当前线程的执行。
     * 该方法用于停止当前线程，确保线程以正确的方式停止。
     * 首先检查是否设置了安全管理器，如果设置了，则进行相应的安全检查。
     * 如果当前线程不是主线程，则检查是否有停止线程的权限。
     * 注意：此方法是 final 的，意味着不能被子类重写，确保了停止行为的一致性和安全性。
     */
    @Deprecated
    public final void stop() {
        // 检查是否设置了安全管理器
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            // 执行安全检查，确保当前线程有权限停止线程
            checkAccess();
            if (this != Thread.currentThread()) {
                // 如果尝试停止其他线程，检查是否有相应的权限
                security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
            }
        }
        // 状态值为零表示 "NEW"，由于持有锁，状态不会变为非 "NEW"
        if (threadStatus != 0) {
            // 如果线程已被挂起，则恢复它；否则，不做任何操作
            resume();
        }

        // 虚拟机可以处理所有线程状态
        // 使用低级 API stop0 停止线程，并抛出 ThreadDeath 异常
        stop0(new ThreadDeath());
    }


    /**
     * 暴力停止线程
     */
    @Deprecated
    public final synchronized void stop(Throwable obj) {
        throw new UnsupportedOperationException();
    }


    /**
     * 中断线程的执行.
     * 此方法旨在请求中断线程，以便它可以检查中断状态并据此采取适当的操作.
     * 如果当前线程不是调用此方法的线程，则首先检查访问权限.
     * 注意：此方法主要处理线程的中断逻辑，包括设置中断标志和调用底层的中断方法.
     */
    public void interrupt() {
        // 如果当前线程不是调用此方法的线程，则检查访问权限
        if (this != Thread.currentThread())
            checkAccess();

        // 同步blockerLock对象，以确保线程安全
        synchronized (blockerLock) {
            // 获取当前线程的中断块（Interruptible对象）
            Interruptible b = blocker;
            // 如果中断块不为空
            if (b != null) {
                // 设置中断标志
                interrupt0();
                // 调用中断块的中断方法，并传递当前线程
                b.interrupt(this);
                // 退出方法
                return;
            }
        }
        // 如果没有中断块，或者中断块为空，则直接设置中断标志
        interrupt0();
    }


    /**
     * 中断当前正在执行的线程，如果线程已被中断，则返回true，否则返回false并中断线程
     * 此方法与Thread类的interrupt方法不同，它专门用于处理当前线程的中断状态
     * @return 如果当前线程已经被中断，则返回true；否则返回false，并将线程的中断状态设置为true
     */
    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }


    public boolean isInterrupted() {
        return isInterrupted(false);
    }


    private native boolean isInterrupted(boolean ClearInterrupted);


    @Deprecated
    public void destroy() {
        throw new NoSuchMethodError();
    }


    public final native boolean isAlive();


    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }


    @Deprecated
    public final void resume() {
        checkAccess();
        resume0();
    }


    /**
     * 设置线程的优先级。
     * 优先级的设定是在线程组的范围内进行的，确保线程的优先级不会超出允许的范围。
     * 如果指定的优先级超出了允许的范围，将抛出IllegalArgumentException异常。
     * 如果线程所属的线程组存在，并且指定的优先级超过了线程组的最大优先级，
     * 则会将线程的优先级设置为线程组的最大优先级。
     */
    public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess(); // 检查是否有权限修改线程优先级
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if ((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority); // 设置线程的优先级，可能涉及native方法调用
        }
    }


    public final int getPriority() {
        return priority;
    }


    public final synchronized void setName(String name) {
        checkAccess();
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }

        this.name = name;
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }


    public final String getName() {
        return name;
    }


    public final ThreadGroup getThreadGroup() {
        return group;
    }


    /**
     * 该方法返回当前线程的线程组中的活动线程数。
     */
    public static int activeCount() {
        return currentThread().getThreadGroup().activeCount();
    }


    public static int enumerate(Thread tarray[]) {
        return currentThread().getThreadGroup().enumerate(tarray);
    }


    @Deprecated
    public native int countStackFrames();


    /**
     * 等待当前线程终止或达到指定的毫秒数
     * 此方法是最终的，不能被子类覆盖，并且是同步的，以防止多个线程同时修改线程的状态
     * @param millis 等待的最大时间，以毫秒为单位如果参数为0，则等待无限期
     * @throws InterruptedException 如果其他线程中断当前线程，将抛出此异常
     * @throws IllegalArgumentException 如果指定的等待时间小于0，将抛出此异常
     */
    public final synchronized void join(long millis)
            throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;

        // 检查等待时间是否为负数，如果是，则抛出异常
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        // 如果等待时间为0，无限期等待线程终止
        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            // 在指定时间内等待线程终止
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }


    public final synchronized void join(long millis, int nanos)
            throws InterruptedException {

        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                    "nanosecond timeout value out of range");
        }

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        join(millis);
    }


    public final void join() throws InterruptedException {
        join(0);
    }


    public static void dumpStack() {
        new Exception("Stack trace").printStackTrace();
    }


    public final void setDaemon(boolean on) {
        checkAccess();
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
        daemon = on;
    }


    public final boolean isDaemon() {
        return daemon;
    }


    public final void checkAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkAccess(this);
        }
    }


    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                    "" + "]";
        }
    }


    @CallerSensitive
    public ClassLoader getContextClassLoader() {
        if (contextClassLoader == null)
            return null;
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            ClassLoader.checkClassLoaderPermission(contextClassLoader,
                    Reflection.getCallerClass());
        }
        return contextClassLoader;
    }

    public void setContextClassLoader(ClassLoader cl) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("setContextClassLoader"));
        }
        contextClassLoader = cl;
    }

    public static native boolean holdsLock(Object obj);

    private static final StackTraceElement[] EMPTY_STACK_TRACE
            = new StackTraceElement[0];


    public StackTraceElement[] getStackTrace() {
        if (this != Thread.currentThread()) {
            // check for getStackTrace permission
            SecurityManager security = System.getSecurityManager();
            if (security != null) {
                security.checkPermission(
                        SecurityConstants.GET_STACK_TRACE_PERMISSION);
            }
            // optimization so we do not call into the vm for threads that
            // have not yet started or have terminated
            if (!isAlive()) {
                return EMPTY_STACK_TRACE;
            }
            StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[]{this});
            StackTraceElement[] stackTrace = stackTraceArray[0];
            // a thread that was alive during the previous isAlive call may have
            // since terminated, therefore not having a stacktrace.
            if (stackTrace == null) {
                stackTrace = EMPTY_STACK_TRACE;
            }
            return stackTrace;
        } else {
            // Don't need JVM help for current thread
            return (new Exception()).getStackTrace();
        }
    }

    public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
        // check for getStackTrace permission
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                    SecurityConstants.GET_STACK_TRACE_PERMISSION);
            security.checkPermission(
                    SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
        }

        // Get a snapshot of the list of all threads
        Thread[] threads = getThreads();
        StackTraceElement[][] traces = dumpThreads(threads);
        Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
        for (int i = 0; i < threads.length; i++) {
            StackTraceElement[] stackTrace = traces[i];
            if (stackTrace != null) {
                m.put(threads[i], stackTrace);
            }
            // else terminated so we don't put it in the map
        }
        return m;
    }


    private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
            new RuntimePermission("enableContextClassLoaderOverride");

    /**
     * cache of subclass security audit results
     */
    /* Replace with ConcurrentReferenceHashMap when/if it appears in a future
     * release */
    private static class Caches {
        /**
         * cache of subclass security audit results
         */
        static final ConcurrentMap<WeakClassKey, Boolean> subclassAudits =
                new ConcurrentHashMap<>();

        /**
         * queue for WeakReferences to audited subclasses
         */
        static final ReferenceQueue<Class<?>> subclassAuditsQueue =
                new ReferenceQueue<>();
    }

    /**
     * Verifies that this (possibly subclass) instance can be constructed
     * without violating security constraints: the subclass must not override
     * security-sensitive non-final methods, or else the
     * "enableContextClassLoaderOverride" RuntimePermission is checked.
     */
    private static boolean isCCLOverridden(Class<?> cl) {
        if (cl == Thread.class)
            return false;

        processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
        WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
        Boolean result = Caches.subclassAudits.get(key);
        if (result == null) {
            result = Boolean.valueOf(auditSubclass(cl));
            Caches.subclassAudits.putIfAbsent(key, result);
        }

        return result.booleanValue();
    }

    /**
     * Performs reflective checks on given subclass to verify that it doesn't
     * override security-sensitive non-final methods.  Returns true if the
     * subclass overrides any of the methods, false otherwise.
     */
    private static boolean auditSubclass(final Class<?> subcl) {
        Boolean result = AccessController.doPrivileged(
                new PrivilegedAction<Boolean>() {
                    public Boolean run() {
                        for (Class<?> cl = subcl;
                             cl != Thread.class;
                             cl = cl.getSuperclass()) {
                            try {
                                cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                            try {
                                Class<?>[] params = {ClassLoader.class};
                                cl.getDeclaredMethod("setContextClassLoader", params);
                                return Boolean.TRUE;
                            } catch (NoSuchMethodException ex) {
                            }
                        }
                        return Boolean.FALSE;
                    }
                }
        );
        return result.booleanValue();
    }

    private native static StackTraceElement[][] dumpThreads(Thread[] threads);

    private native static Thread[] getThreads();


    public long getId() {
        return tid;
    }


    /**
     * 线程生命周期
     */
    public enum State {

        // 新建
        NEW,

        // 就绪
        RUNNABLE,

        // 阻塞
        BLOCKED,

        // 无限等待
        WAITING,

        // 超时等待
        TIMED_WAITING,

        // 结束
        TERMINATED;
    }


    public State getState() {
        // get current thread state
        return sun.misc.VM.toThreadState(threadStatus);
    }

    // Added in JSR-166


    @FunctionalInterface
    public interface UncaughtExceptionHandler {
        void uncaughtException(Thread t, Throwable e);
    }

    private volatile UncaughtExceptionHandler uncaughtExceptionHandler;

    private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;


    public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(
                    new RuntimePermission("setDefaultUncaughtExceptionHandler")
            );
        }

        defaultUncaughtExceptionHandler = eh;
    }

    public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler() {
        return defaultUncaughtExceptionHandler;
    }


    public UncaughtExceptionHandler getUncaughtExceptionHandler() {
        return uncaughtExceptionHandler != null ?
                uncaughtExceptionHandler : group;
    }

    public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
        checkAccess();
        uncaughtExceptionHandler = eh;
    }


    private void dispatchUncaughtException(Throwable e) {
        getUncaughtExceptionHandler().uncaughtException(this, e);
    }


    static void processQueue(ReferenceQueue<Class<?>> queue,
                             ConcurrentMap<? extends
                                     WeakReference<Class<?>>, ?> map) {
        Reference<? extends Class<?>> ref;
        while ((ref = queue.poll()) != null) {
            map.remove(ref);
        }
    }


    static class WeakClassKey extends WeakReference<Class<?>> {

        private final int hash;


        WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
            super(cl, refQueue);
            hash = System.identityHashCode(cl);
        }


        @Override
        public int hashCode() {
            return hash;
        }


        @Override
        public boolean equals(Object obj) {
            if (obj == this)
                return true;

            if (obj instanceof WeakClassKey) {
                Object referent = get();
                return (referent != null) &&
                        (referent == ((WeakClassKey) obj).get());
            } else {
                return false;
            }
        }
    }


    @sun.misc.Contended("tlr")
    long threadLocalRandomSeed;

    @sun.misc.Contended("tlr")
    int threadLocalRandomProbe;

    @sun.misc.Contended("tlr")
    int threadLocalRandomSecondarySeed;

    private native void setPriority0(int newPriority);

    private native void stop0(Object o);

    private native void suspend0();

    private native void resume0();

    private native void interrupt0();

    private native void setNativeName(String name);
}
